#!/usr/bin/env python3
"""
紧急回滚脚本
"""
import sys
import os
import asyncio
import argparse
from pathlib import Path

# 添加项目根目录到Python路径
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

from app.core.database import get_db_context
from app.services.deployment_service import DeploymentService
from app.models.release import Release, ReleaseStatus, Environment
from app.core.config import current_settings

logger = logging.getLogger(__name__)


async def emergency_rollback(version: str, environment: str = "production", reason: str = "紧急回滚"):
    """执行紧急回滚"""
    try:
        print(f"开始紧急回滚到版本: {version}")
        print(f"目标环境: {environment}")
        print(f"回滚原因: {reason}")
        print("=" * 50)
        
        with get_db_context() as db:
            deployment_service = DeploymentService(db)
            
            # 查找目标版本
            target_release = db.query(Release).filter(
                Release.version == version,
                Release.environment == Environment(environment),
                Release.status == ReleaseStatus.SUCCESS
            ).first()
            
            if not target_release:
                print(f"错误: 版本 {version} 在 {environment} 环境中不存在或未成功发布")
                return False
            
            print(f"找到目标版本: {target_release.version}")
            print(f"发布时间: {target_release.deployed_at}")
            print(f"发布人: {target_release.deployed_by}")
            
            # 查找当前版本
            current_release = db.query(Release).filter(
                Release.environment == Environment(environment),
                Release.status.in_([ReleaseStatus.SUCCESS, ReleaseStatus.IN_PROGRESS])
            ).order_by(Release.deployed_at.desc()).first()
            
            if current_release:
                print(f"当前版本: {current_release.version}")
                print(f"当前状态: {current_release.status}")
                
                if current_release.version == version:
                    print("当前版本已经是目标版本，无需回滚")
                    return True
            
            # 执行回滚
            print("\n开始执行回滚...")
            rollback_result = await deployment_service.rollback_release(
                target_release.id,
                reason,
                "emergency_rollback_script"
            )
            
            if rollback_result.get("success"):
                print("✅ 紧急回滚执行成功！")
                print(f"回滚到版本: {version}")
                return True
            else:
                print("❌ 紧急回滚执行失败！")
                print(f"错误信息: {rollback_result.get('error')}")
                return False
                
    except Exception as e:
        print(f"❌ 紧急回滚过程中发生错误: {e}")
        return False


async def list_available_versions(environment: str = "production"):
    """列出可用的版本"""
    try:
        print(f"列出 {environment} 环境中的可用版本:")
        print("=" * 50)
        
        with get_db_context() as db:
            releases = db.query(Release).filter(
                Release.environment == Environment(environment),
                Release.status == ReleaseStatus.SUCCESS
            ).order_by(Release.deployed_at.desc()).all()
            
            if not releases:
                print(f"在 {environment} 环境中没有找到成功的发布记录")
                return
            
            for release in releases:
                print(f"版本: {release.version}")
                print(f"  描述: {release.description}")
                print(f"  发布时间: {release.deployed_at}")
                print(f"  发布人: {release.deployed_by}")
                print(f"  策略: {release.strategy}")
                print()
                
    except Exception as e:
        print(f"获取版本列表失败: {e}")


async def check_system_status():
    """检查系统状态"""
    try:
        print("检查系统状态:")
        print("=" * 50)
        
        with get_db_context() as db:
            # 检查数据库连接
            try:
                db.execute("SELECT 1")
                print("✅ 数据库连接正常")
            except Exception as e:
                print(f"❌ 数据库连接失败: {e}")
                return False
            
            # 检查各环境的发布状态
            environments = ["production", "staging", "testing"]
            for env in environments:
                try:
                    env_enum = Environment(env)
                    latest_release = db.query(Release).filter(
                        Release.environment == env_enum
                    ).order_by(Release.deployed_at.desc()).first()
                    
                    if latest_release:
                        print(f"✅ {env} 环境: {latest_release.version} ({latest_release.status})")
                    else:
                        print(f"⚠️  {env} 环境: 无发布记录")
                except Exception as e:
                    print(f"❌ {env} 环境检查失败: {e}")
            
            return True
            
    except Exception as e:
        print(f"系统状态检查失败: {e}")
        return False


def main():
    """主函数"""
    parser = argparse.ArgumentParser(description="SaaS平台发布与回滚系统 - 紧急回滚脚本")
    parser.add_argument("--version", "-v", help="目标版本号")
    parser.add_argument("--environment", "-e", default="production", 
                       choices=["production", "staging", "testing"],
                       help="目标环境 (默认: production)")
    parser.add_argument("--reason", "-r", default="紧急回滚", help="回滚原因")
    parser.add_argument("--list", "-l", action="store_true", help="列出可用版本")
    parser.add_argument("--status", "-s", action="store_true", help="检查系统状态")
    parser.add_argument("--force", "-f", action="store_true", help="强制回滚（跳过确认）")
    
    args = parser.parse_args()
    
    print("SaaS平台发布与回滚系统 - 紧急回滚脚本")
    print("=" * 60)
    
    if args.status:
        # 检查系统状态
        asyncio.run(check_system_status())
        return
    
    if args.list:
        # 列出可用版本
        asyncio.run(list_available_versions(args.environment))
        return
    
    if not args.version:
        print("错误: 必须指定目标版本号")
        print("使用 --help 查看帮助信息")
        sys.exit(1)
    
    # 确认回滚操作
    if not args.force:
        print(f"⚠️  警告: 即将执行紧急回滚操作")
        print(f"   目标版本: {args.version}")
        print(f"   目标环境: {args.environment}")
        print(f"   回滚原因: {args.reason}")
        print()
        
        confirm = input("确认执行回滚操作吗？(输入 'yes' 确认): ")
        if confirm.lower() != "yes":
            print("回滚操作已取消")
            return
    
    # 执行回滚
    success = asyncio.run(emergency_rollback(
        args.version,
        args.environment,
        args.reason
    ))
    
    if success:
        print("\n🎉 紧急回滚操作完成！")
        print("请检查系统状态，确保服务正常运行。")
    else:
        print("\n💥 紧急回滚操作失败！")
        print("请检查错误信息并手动处理。")
        sys.exit(1)


if __name__ == "__main__":
    import logging
    logging.basicConfig(level=logging.INFO)
    main()
